<!DOCTYPE html>

<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<h3>变量作用域</h3>
		<ul>
			<li>在function外部定义的变量，无论是否使用var，均在global空间中</li>
			<li>在function内部使用var定义的变量，仅存在于function所在范围内</li>
			<li>在function内部未使用var定义的变量，仍然位于global空间中</li>
			<li>JavaScript没有"块级别"的作用域</li>
			<button onclick="funcTest1()">运行例子</button>
		</ul>
		<script>
			g1 = 1;
			var g2 = 2;
			function foo(){
				g1 = 10;
				g2 = 20;
				g3 = 30;
				var g4 = 40;
			}
			//console.log(g3);  // 错误，此时foo函数尚未执行，g3并不存在
			g3 = 3;				// 此g3就是foo中的g3
			//console.log(g4);	// 错误, g4未定义
			function funcTest1(){
				foo();				
				console.log(g1);
				console.log(g2);
				console.log(g3);	// 请注意，因为g3=3在foo()函数执行之前就已经运行，因此此处g3为30
				
				if(true){
					var block = 50;
				}
				console.log(block);
			}
		</script>
	
		<h3>变量隐藏</h3>
		<ul>
			<li>如果函数内部通过var定义了与global空间中相同名称的变量，那么函数内部的该变量将隐藏global中的变量</li>
			<li>如果函数形参名称与外部某变量名称相同，则形参隐藏外部变量</li>
			<li>后定义的变量隐藏(也可认为是覆盖)了之前定义的变量</li>
			<li>global控件中的数据可通过window对象进行访问</li>
			<button onclick="funcTest2()">运行例子</button>
		</ul>
		<script>
			var color = "red";
			function changeColor(){
				var color = "green";
				console.log(color);			// 局部的color
				console.log(window.color);	// 通过window对象可访问global中的数据
			}
			function changeColor(color){
				var newColor = color;		// 形参color，不是global中的color
				console.log(newColor);
			}
			function funcTest2(){
				console.log(color);			// global中的color
				changeColor();
				console.log(color);			// global中的color
				
				changeColor("yellow");
			}
		</script>
	
		<h3>with关键字</h3>
		<ul>
			<li>with关键字可以在其作用域块内，设置一个指定的对象作为Scope</li>
			<li>对于其作用域块内的变量，如果不是在局部定义的，则会检查是否是其指定对象的成员</li>
			<li>with经常伴随效率降低，不建议常用</li>
			<button onclick="funcTest3()">运行例子</button>
		</ul>
		<script>
			function funcTest3(){
				with(window.location){
					console.log(href);
					console.log(search);
					console.log(host);
				}
				//可用于简化语句，
				var o=document.createElement("div");
				with(o){
    				style.cursor="pointer";
    				style.zIndex="100";
    				innerHTML="aaaa";
				}
				document.body.appendChild(o);
			}
		</script>
		
		<h4>try-catch-finally</h4>
		<ul>
			<li>try、catch、finally块中定义的变量可以在各块中直接访问</li>
			<button onclick="funcTest4()">运行例子</button>
		</ul>
		<script>
			function funcTest4(){
				try{
					var i = 10;
					var j = 2;
					var k = i / J;		// 故意写错变量名j，以便产生异常
				}catch(error){
					console.log(error);
				}finally{
					console.log("i=" + i + ":j=" + j);
				}
			}
		</script>
	</body>
</html>
